package ar.uba.dc.sistemas.monitorRW;

/**
 * Esta implementacion da prioridades a lectores y escritores por orden de llegada.
 * Si llegan varios lectores se permite la lectura compartida.
 *
 * @author Hernan Berroja Albiz / German del Tuffo
 * @version 0.1
 */

public class TakeANumberMonitor implements MultipleReadersWritersMonitor {
    /**
     * Cantidad de lectores leyendo. 
     */
    protected int cantLectores = 0;
    /**
     * Take a number
     */
    protected int siguienteNumero = 0;
    /**
     * Numero que esta siendo procesado.
     */
    protected int actual = 0;

    /**
     * Resetea el monitor.
     */
    public void reset() {
        cantLectores = 0;
        siguienteNumero = 0;
        actual = 0;
    }

    /**
     * Este metodo es llamado para comenzar a leer el objeto compartido.
     *
     * 
     */
    public synchronized void comenzarLectura()
            throws InterruptedException {
        int myNumber = siguienteNumero++;
        while (actual != myNumber) wait();
        cantLectores++;
        actual++;
        notifyAll();
    }

    /**
     * Este metodo es llamado cuando se termina de leer el objeto compartido.
     */
    public synchronized void detenerLectura() {
        cantLectores--;
        if (cantLectores == 0) notifyAll();
    }

    /**
     * Este metodo es llamado para comenzar a escribir en el objeto compartido.
     */
    public synchronized void comenzarEscritura()
            throws InterruptedException {
        int myNumber = siguienteNumero++;
        while (actual != myNumber) wait();
        while (cantLectores > 0) wait();
    }

    /**
     * Este metodo es llamado cuando se termina de escribir en el objeto compartido.
     */
    public synchronized void detenerEscritura() {
        actual++;
        notifyAll();
    }

    /**
     * Este metodo brinda informacion acerca del monitor
     *
     */
    public String getMonitorInfo() {
        return "Take-A-Number Monitor";
    }
}

